package com.ruoyi.faq.service.impl;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.faq.domain.FaqKnowledge;
import com.ruoyi.faq.domain.FaqUserQuestion;
import com.ruoyi.faq.mapper.FaqKnowledgeMapper;
import com.ruoyi.faq.mapper.FaqUserQuestionMapper;
import com.ruoyi.faq.service.IFaqService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class IFaqServiceImpl implements IFaqService {
    @Autowired
    private FaqKnowledgeMapper faqKnowledgeMapper;

    @Autowired
    private FaqUserQuestionMapper faqUserQuestionMapper;

    @Override
    public String smartAnswer(String question) {
        // 1. 对用户问题进行分词
        List<String> questionWords = HanLP.segment(question)
                .stream()
                .map(Term::toString)
                .collect(Collectors.toList());


        // 2. 获取所有FAQ
        FaqKnowledge faqKnowledge = new FaqKnowledge();
        faqKnowledge.setDelFlag("0");
        List<FaqKnowledge> allFaqs = faqKnowledgeMapper.selectFaqKnowledgeList(faqKnowledge);

        // 3. 计算相似度并找出最匹配的FAQ
        FaqKnowledge bestMatch = null;
        double maxSimilarity = 0.0;

        for (FaqKnowledge faq : allFaqs) {
            // 计算问题相似度
            double similarity = calculateSimilarity(question, faq.getQuestion());
            if (similarity > maxSimilarity) {
                maxSimilarity = similarity;
                bestMatch = faq;
            }
        }

        // 4. 记录用户提问
        FaqUserQuestion userQuestion = new FaqUserQuestion();
        userQuestion.setQuestion(question);
        userQuestion.setMatchedFaqId(bestMatch != null ? bestMatch.getId() : null);
        userQuestion.setSimilarity(new BigDecimal(maxSimilarity));
        userQuestion.setUserId(SecurityUtils.getUserId());
        faqUserQuestionMapper.insertFaqUserQuestion(userQuestion);

        // 5. 返回答案
        if (bestMatch != null && maxSimilarity >= 0.6) { // 设置相似度阈值
            // 更新查看次数
            bestMatch.setViewCount(bestMatch.getViewCount() + 1);
            faqKnowledgeMapper.updateFaqKnowledge(bestMatch);
            return bestMatch.getAnswer();
        }

        return "抱歉，我暂时无法理解您的问题，请尝试换种方式提问或联系人工客服。";
    }

    /**
     * 计算两个字符串的相似度
     */
    private double calculateSimilarity(String str1, String str2) {
        // 使用余弦相似度算法
        List<String> words1 = HanLP.segment(str1)
                .stream()
                .map(Term::toString)
                .collect(Collectors.toList());
        List<String> words2 = HanLP.segment(str2)
                .stream()
                .map(Term::toString)
                .collect(Collectors.toList());

        // 构建词频向量
        Map<String, Integer> map1 = new HashMap<>();
        Map<String, Integer> map2 = new HashMap<>();

        for (String word : words1) {
            map1.put(word, map1.getOrDefault(word, 0) + 1);
        }
        for (String word : words2) {
            map2.put(word, map2.getOrDefault(word, 0) + 1);
        }

        // 计算余弦相似度
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;

        for (String word : map1.keySet()) {
            if (map2.containsKey(word)) {
                dotProduct += map1.get(word) * map2.get(word);
            }
            norm1 += map1.get(word) * map1.get(word);
        }

        for (Integer value : map2.values()) {
            norm2 += value * value;
        }

        if (norm1 == 0.0 || norm2 == 0.0) {
            return 0.0;
        }

        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }
}
